﻿using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using NetBay.Core.BusinessEntities.Workflow;

using Rio.Flow.Application.Models.Flow;
using Rio.Framework.Localisation;
using Rio.Framework.Pages.AppCode.Helpers;
using Rio.Framework.Pages.Context;

using Rio.Framework.Pages.Workflow.Models;

namespace Rio.Framework.Pages.Workflow
{
    public partial class FlowItemsPanel : INotifyPropertyChanged
    {
        #region Fields

        public static readonly DependencyProperty FlowStructureProperty =
            DependencyProperty.Register("FlowStructure", typeof(ObservableCollection<FlowTreeModel>), typeof(FlowItemsPanel), null);
        public static readonly DependencyProperty SelectedDataItemTreeViewProperty =
            DependencyProperty.Register("SelectedDataItemTreeView", typeof(DataItemTreeView), typeof(FlowItemsPanel), null);

        private LoadingIndicatorManager _busyIndicator = new LoadingIndicatorManager();

        #endregion Fields

        #region Constructors

        public FlowItemsPanel()
        {
            InitializeComponent();
        }

        #endregion Constructors

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion Events

        #region Properties

        public LoadingIndicatorManager BusyIndicator
        {
            get { return _busyIndicator; }
            set
            {
                _busyIndicator = value;
                _busyIndicator.PropertyChanged += delegate
                {
                    OnPropertyChanged("BusyIndicator");
                };
            }
        }

        public ObservableCollection<FlowTreeModel> FlowStructure
        {
            get { return (ObservableCollection<FlowTreeModel>)GetValue(FlowStructureProperty); }
            set { SetValue(FlowStructureProperty, value); }
        }

        public DataItemTreeView SelectedDataItemTreeView
        {
            get { return (DataItemTreeView)GetValue(SelectedDataItemTreeViewProperty); }
            set { SetValue(SelectedDataItemTreeViewProperty, value); }
        }

        #endregion Properties

        #region Methods

        /// <summary>
        /// Clears this instance.
        /// </summary>
        public void Clear()
        {
            if (FlowStructure != null)
            {
                FlowStructure.Clear();
            }

            PanelBar.Items.Clear();
        }

        /// <summary>
        /// Adds the WKF tuple.
        /// </summary>
        /// <param name="w">The w.</param>
        /// <param name="itemType"></param>
        /// <param name="subItemType"></param>
        public void AddWkfTuple(WkfTuple w, WorkflowTreeItemType itemType, WorkflowTreeSubItemType subItemType)
        {
            FlowTreeModel flowTreeModel = null;

            /*
             * GRY : 05/08/2011
             * If the receiver of the workflow doesn't have rights on this organization anf foldetype,
             * we don't display it. (Waiting new rights and Rio manager Specs, implements new rights after).
             */

            bool userHaveRights = true;

            //If the Organization is not in FlowSructure
            if (FlowStructure != null && !FlowStructure.Any(i => i.Organization.Identifier == w.OrganizationId))
            {
                if (GlobalWebContext.CurrentUser.GroupList.SelectMany(g => g.OrganizationList).Where(o => o.Identifier == w.OrganizationId).Any(o => o.Identifier == w.OrganizationId))
                {
                    var organization = GlobalWebContext.CurrentUser.GroupList.SelectMany(g => g.OrganizationList).Where(o => o.Identifier == w.OrganizationId).FirstOrDefault();

                    //Create and get Organization
                    flowTreeModel = new FlowTreeModel
                                        {
                                            Organization = organization
                                        };

                    //Create and add to display the Item
                    FlowPanelBarItem flowPanelBarItem = new FlowPanelBarItem
                                                            {
                                                                FlowTreeModel = flowTreeModel
                                                            };

                    flowPanelBarItem.ItemSelected += FlowPanelBarItemItemSelected;

                    //Add FlowTreeModel
                    FlowStructure.Add(flowTreeModel);

                    PanelBar.Items.Insert(0, flowPanelBarItem);
                }
                else
                {
                    userHaveRights = false;
                }
            }
            else
            {
                if (FlowStructure != null)
                {
                    flowTreeModel = FlowStructure.Where(i => i.Organization.Identifier == w.OrganizationId).SingleOrDefault();
                }
            }

            if (userHaveRights
                && GlobalWebContext.CurrentUser.GroupList
                            .SelectMany(g => g.OrganizationList)
                            .SelectMany(o => o.FolderTypesList).Any(ft => ft.Identifier == w.FolderTypeId))
            {
                DataItemTreeViewCollection dataItemTreeViewCollection = null;
                if (FlowStructure != null && !FlowStructure.SelectMany(f => f.Items).Any(ft => ft.Key.Identifier == w.FolderTypeId))
                {
                    dataItemTreeViewCollection = new DataItemTreeViewCollection(null);

                    //Get FolderType and add collection of items
                    if (flowTreeModel != null)
                    {
                        flowTreeModel.Items.Add(
                            GlobalWebContext.CurrentUser.GroupList
                                .SelectMany(g => g.OrganizationList)
                                .SelectMany(o => o.FolderTypesList)
                                .Where(ft => ft.Identifier == w.FolderTypeId)
                                .FirstOrDefault(),
                            dataItemTreeViewCollection);
                    }
                }
                else
                {
                    if (FlowStructure != null)
                    {
                        dataItemTreeViewCollection = FlowStructure.SelectMany(f => f.Items).Where(i => i.Key.Identifier == w.FolderTypeId).Select(i => i.Value).SingleOrDefault();
                    }
                }

                DataItemTreeView dataItemTreeView;
                if (dataItemTreeViewCollection != null && dataItemTreeViewCollection.Any(i => i.ItemType == itemType))
                {
                    dataItemTreeView = dataItemTreeViewCollection.Where(i => i.ItemType == itemType).SingleOrDefault();
                }
                else
                {
                    //Create parent-item (Reception or Send) and fill specials properties
                    dataItemTreeView = new DataItemTreeView
                                           {
                                               ItemType = WorkflowTreeItemType.None,
                                               SubItemType = WorkflowTreeSubItemType.None
                                           };

                    switch (itemType)
                    {
                        case WorkflowTreeItemType.Reception:
                            dataItemTreeView.iIdRepertory = (int)Repertory.RECEIPT;
                            dataItemTreeView.sText = Resx.GetLabel(ResxFlowPage.FLOW_RECEIVE);
                            dataItemTreeView.sImageSrc = "../Assets/Images/Mail_receive.png";
                            dataItemTreeView.ItemType = WorkflowTreeItemType.Reception;

                            if (dataItemTreeViewCollection != null)
                                dataItemTreeViewCollection.Insert(0, dataItemTreeView);

                            break;
                        case WorkflowTreeItemType.Send:
                            dataItemTreeView.iIdRepertory = (int)Repertory.SEND;
                            dataItemTreeView.sText = Resx.GetLabel(ResxFlowPage.FLOW_SENT);
                            dataItemTreeView.sImageSrc = "../Assets/Images/Mail_send.png";
                            dataItemTreeView.ItemType = WorkflowTreeItemType.Send;

                            if (dataItemTreeViewCollection != null)
                                dataItemTreeViewCollection.Add(dataItemTreeView);

                            break;
                    }
                }

                //Create sub-item (Processing or Done) and fill specials properties
                DataItemTreeView subItem = new DataItemTreeView
                                               {
                    ItemType = itemType,
                    SubItemType = subItemType,
                    FolderTypeId = w.FolderTypeId,
                    OrganizationId = w.OrganizationId
                };

                switch (subItemType)
                {
                    case WorkflowTreeSubItemType.Processing:
                        subItem.sText = Resx.GetLabel(ResxFlowPage.FLOW_WAITING);
                        subItem.sImageSrc = "../Assets/Images/flow_processing.png";

                        if (dataItemTreeView != null)
                            dataItemTreeView.Items.Insert(0, subItem);

                        break;
                    case WorkflowTreeSubItemType.Completed:
                        subItem.sText = Resx.GetLabel(ResxFlowPage.FLOW_PROCESSED);
                        subItem.sImageSrc = "../Assets/Images/flow_finished.png";

                        if (dataItemTreeView != null)
                            dataItemTreeView.Items.Add(subItem);

                        break;
                }

                //Fill common properties for sub-item
                subItem.NumberItem = w.MessageTotalCount;
                subItem.NumberNewItem = w.MessageCount;
                subItem.bIsExpanded = subItem.NumberNewItem > 0;

                //Fill common properties for parent-item
                if (dataItemTreeView != null) {
                    dataItemTreeView.NumberItem = (from item in dataItemTreeView.Items
                                                   select item.NumberItem).Sum();
                    dataItemTreeView.NumberNewItem = (from item in dataItemTreeView.Items
                                                      select item.NumberNewItem).Sum();
                    dataItemTreeView.TextFont = FontWeights.Normal;
                    dataItemTreeView.bIsExpanded = dataItemTreeView.NumberNewItem > 0;
                }

                PanelBar.Items.Cast<FlowPanelBarItem>().ToList().ForEach(i => i.LoadStructure());

                PanelBar.Items.Cast<FlowPanelBarItem>().ToList().OrderBy(i => i.FlowTreeModel.Organization.Name);
            }
        }


        /// <summary>
        /// Flows the panel bar item_ item selected.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="selectedItem">The selected item.</param>
        private void FlowPanelBarItemItemSelected(object sender, DataItemTreeView selectedItem)
        {
            SelectedDataItemTreeView = selectedItem;
        }

        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion Methods
    }
}